"""
Global server configuration management for MCPM v2.0

This module manages the global server registry where all servers are stored centrally.
Profiles tag servers but don't own them - servers exist globally.
"""

import json
import logging
import os
from datetime import datetime
from typing import Dict, List, Optional

from sys_intd.constant import DEFAULT_LOCAL_AGENT_CONFIG_PATH
from sys_intd.schema import AgentConfig

logger = logging.getLogger(__name__)


class AgentManager:
    """基于Pydantic模型的智能体管理器，提供类型安全的增删改查功能"""

    def __init__(self, agent_path: str = DEFAULT_LOCAL_AGENT_CONFIG_PATH):
        self.agent_path = os.path.expanduser(agent_path)
        self.agent_dir = os.path.dirname(self.agent_path)

        self._ensure_dirs()
        self._agents: Dict[str, AgentConfig] = self._load_agents()

    def _ensure_dirs(self) -> None:
        """确保配置目录存在"""
        os.makedirs(self.agent_dir, exist_ok=True)

    def _load_agents(self) -> Dict[str, AgentConfig]:
        """从配置文件加载智能体，转换为AgentConfig对象"""
        if not os.path.exists(self.agent_path):
            return {}

        try:
            with open(self.agent_path, 'r', encoding='utf-8') as f:
                data = json.load(f)

            # 将JSON数据转换为AgentConfig对象字典
            agents = {}
            for name, agent_data in data.items():
                # 处理时间字段的类型转换
                if 'create_time' in agent_data:
                    agent_data['create_time'] = datetime.fromisoformat(agent_data['create_time'])
                if 'update_time' in agent_data:
                    agent_data['update_time'] = datetime.fromisoformat(agent_data['update_time'])

                agents[name] = AgentConfig(**agent_data)
            return agents

        except json.JSONDecodeError:
            raise ValueError(f"配置文件 {self.agent_path} 格式错误")
        except Exception as e:
            raise RuntimeError(f"加载智能体配置失败: {str(e)}")

    def _save_agents(self) -> None:
        """将智能体配置保存到文件"""
        try:
            serialized = {}
            for name, agent in self._agents.items():
                agent_dict = agent.model_dump()
                # 处理datetime类型为ISO字符串
                agent_dict['create_time'] = agent.create_time.isoformat()
                serialized[name] = agent_dict

            with open(self.agent_path, 'w', encoding='utf-8') as f:
                json.dump(serialized, f, ensure_ascii=False, indent=2)

        except Exception as e:
            raise RuntimeError(f"保存智能体配置失败: {str(e)}")

    def get_all_agents(self) -> Dict[str, AgentConfig]:
        """获取所有智能体配置"""
        return self._agents.copy()

    def get_agent(self, name: str) -> Optional[AgentConfig]:
        """获取指定名称的智能体"""
        return self._agents.get(name)

    def add_agent(self, agent: AgentConfig) -> None:
        """添加新agent"""
        self._agents[agent.name] = agent
        self._save_agents()

    def update_agent(self, name: str, new_name: Optional[str] = None, mcp_list: Optional[List[str]] = None) -> Optional[
        AgentConfig]:
        """更新智能体配置"""
        if name not in self._agents:
            return None

        agent = self._agents[name]
        old_name = name

        # 处理名称更新
        if new_name and new_name != old_name:
            if new_name in self._agents:
                raise ValueError(f"智能体名称 '{new_name}' 已被占用")
            name = new_name

        # 更新字段
        if mcp_list is not None:
            agent.mcp_list = mcp_list
        if new_name:
            agent.name = new_name

        # 更新时间戳
        agent.update_time = datetime.now()

        # 处理名称变更时的字典键更新
        if old_name != name:
            del self._agents[old_name]

        self._agents[name] = agent
        self._save_agents()
        return agent

    def delete_agent(self, name: str) -> bool:
        """删除智能体"""
        if name in self._agents:
            del self._agents[name]
            self._save_agents()
            return True
        return False

    def search_agents(self, keyword: str) -> Dict[str, AgentConfig]:
        """搜索智能体"""
        results = {}
        keyword_lower = keyword.lower()

        for name, agent in self._agents.items():
            if keyword_lower in name.lower():
                results[name] = agent
                continue

            for mcp in agent.mcp_list:
                if keyword_lower in mcp.lower():
                    results[name] = agent
                    break

        return results

    def list_agents(self) -> List[AgentConfig]:
        """列出所有agents"""
        return list(self._agents.values())
